package main

import "fmt"

// 普通函数： 接收者为值类型时，不能传递指针，反之亦然
// 结构体-方法，关于调用形式如何，决定是值拷贝还是地址拷贝的是 看方法和哪个类型绑定
func main() {
	testNomFunc()
	testStructFunc01()
	testStructFunc02()

}

// 普通函数: 接收者为值类型时，不能传递指针，反之亦然
func testNomFunc() {
	var stu Student = Student{"tom"}
	fmt.Println("model-name=", stu.Name) // tom
	normalFunc(stu)                      //jack
	//nomFunc(&stu)  //报错 Cannot use '&stu' (type *Student) as the type Student
	fmt.Println("model-name=", stu.Name) // tom
}

// 值传递
func normalFunc(stu Student) {
	stu.Name = "jack"
	fmt.Println("普通函数-name=", stu.Name) //jack
}

// 结构体-方法： 接收者为值类型，可以直接使用指针
func testStructFunc01() {
	var stu Student = Student{"tom"}
	fmt.Println("model-name=", stu.Name) // tom
	stu.structValueTypeFunc()            //jack
	(&stu).structValueTypeFunc()         //jack
	fmt.Println("model-name=", stu.Name) // tom
}

func (stu Student) structValueTypeFunc() {
	stu.Name = "jack"
	fmt.Println("方法-name=", stu.Name) //jack
}

// 结构体-方法： 接收者为指针类型，可以直接使用值
func testStructFunc02() {
	var stu Student = Student{"tom"}
	fmt.Println("model-name=", stu.Name) // tom
	(&stu).structPtrTypeFunc()           //jack
	stu.structPtrTypeFunc()              //jack
	fmt.Println("model-name=", stu.Name) // jack
}

func (stu *Student) structPtrTypeFunc() {
	(*stu).Name = "jack"
	fmt.Println("方法-name=", (*stu).Name) //jack
}

type Student struct {
	Name string
}
